﻿using System;
using System.Collections;
using System.Windows.Forms;
using System.IO;

namespace MyMovies
{
    public partial class mainForm : Form
    {
        private Parameters myParam = null;
        private ListViewColumnSorter lvwColumnSorter;

        public mainForm()
        {
            InitializeComponent();
            InitializeData();
        }

        private void InitializeData()
        {
            if (!SqlLiteManagement.CreateDB("MyMovies.db"))
                Application.ExitThread();

            myParam = Parameters.Load("MyMovies.config");
            if (myParam == null)
            {
                myParam = new Parameters();
                myParam.Save("MyMovies.config");
            }

            bool result = false;
            if (bool.TryParse(myParam.ShowScanPath, out result))
            {
                tsmiScan.Visible = result;
                tsmiUpdateOnline.Visible = result;
                tsmiRename.Visible = result;
                tsmDelete.Visible = result;
                tsmTouch.Visible = result;
            }

            ScanFolders.ScanStart += new ScanFolders.MessageEventHandler(ScanFolders_ScanStart);
            ScanFolders.ScanEnd += new ScanFolders.MessageEventHandler(ScanFolders_ScanEnd);
            ScanFolders.ScanProgress += new ScanFolders.MessageEventHandler(ScanFolders_ScanProgress);

            MkvRenamer.ScanStart += new MkvRenamer.MessageEventHandler(MkvRenamer_ScanStart);
            MkvRenamer.ScanEnd += new MkvRenamer.MessageEventHandler(MkvRenamer_ScanEnd);

            lvwColumnSorter = new ListViewColumnSorter();
            this.lsvMain.ListViewItemSorter = lvwColumnSorter;
        }

        protected override void OnLoad(EventArgs e)
        {
            if (Properties.Settings.Default.Pinned)
                splitContainer1.SplitterDistance = this.Height / 2;
            else
                splitContainer1.SplitterDistance = this.Height;
            TableGenre.FillGroup(lsvMain.Groups);
            TableMovies.Fill(lsvMain.Items, lsvMain.Groups);
            //SqlLiteManagement.CloseDB();
            foreach (ColumnHeader col in lsvMain.Columns)
                col.Width = -1;
        }

        #region Events

        private void ScanFolders_ScanEnd(MessageEventArgs e)
        {
            this.Cursor = Cursors.Default;
            TableGenre.FillGroup(lsvMain.Groups);
            TableMovies.Fill(lsvMain.Items, lsvMain.Groups);

            foreach (ColumnHeader col in lsvMain.Columns)
                col.Width = -2;

            tsmOperation.Enabled = true;
            //SqlLiteManagement.CloseDB();
            UpdateStatus(Properties.Resources.Completed);

            if (ScanFolders.DuplicatedFiles.Count > 0)
            {
                duplicatedForm frm = new duplicatedForm(ScanFolders.DuplicatedFiles);
                frm.ShowDialog();
            }
        }

        private void ScanFolders_ScanStart(MessageEventArgs e)
        {
            UpdateStatus(e.Message);
            this.Cursor = Cursors.WaitCursor;
            tsmOperation.Enabled = false;
            SqlLiteManagement.OpenDB("MyMovies.db");
        }

        private void ScanFolders_ScanProgress(MessageEventArgs e)
        {
            UpdateStatus(e.Message);
        }

        private void MkvRenamer_ScanEnd(MessageEventArgs e)
        {
            this.Cursor = Cursors.Default;
            tsmOperation.Enabled = true;
            UpdateStatus(Properties.Resources.Completed);
        }

        private void MkvRenamer_ScanStart(MessageEventArgs e)
        {
            UpdateStatus(e.Message);
            this.Cursor = Cursors.WaitCursor;
            tsmOperation.Enabled = false;
        }

        private void tsmiExit_Click(object sender, EventArgs e)
        {
            Application.ExitThread();
        }

        private void tsmiScan_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(myParam.ScanPath))
            {
                FolderBrowserDialog fbd = new FolderBrowserDialog();
                if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    myParam.ScanPath = fbd.SelectedPath;
                    myParam.Save("MyMovies.config");

                    ScanFolders.Scan(fbd.SelectedPath);
                }
            }
            else
                ScanFolders.Scan(myParam.ScanPath);
        }

        private void tsmiRename_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(myParam.ScanPath))
            {
                FolderBrowserDialog fbd = new FolderBrowserDialog();
                if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    myParam.ScanPath = fbd.SelectedPath;
                    myParam.Save("MyMovies.config");

                    MkvRenamer.Rename(fbd.SelectedPath);
                }
            }
            else
                MkvRenamer.Rename(myParam.ScanPath);
        }

        private void lsvMain_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            // Determine if clicked column is already the column that is being sorted.
            if (e.Column == lvwColumnSorter.SortColumn)
            {
                // Reverse the current sort direction for this column.
                if (lvwColumnSorter.Order == SortOrder.Ascending)
                {
                    lvwColumnSorter.Order = SortOrder.Descending;
                }
                else
                {
                    lvwColumnSorter.Order = SortOrder.Ascending;
                }
            }
            else
            {
                // Set the column number that is to be sorted; default to ascending.
                lvwColumnSorter.SortColumn = e.Column;
                lvwColumnSorter.Order = SortOrder.Ascending;
            }

            // Perform the sort with these new sort options.
            this.lsvMain.Sort();

            if (e.Column == colDownload.Index)
            {
                lsvMain.Groups.Clear();

                foreach (ListViewItem itm in lsvMain.Items)
                {
                    string date = itm.SubItems["colDownload"].Text;
                    ListViewGroup grp = lsvMain.Groups[date];
                    if (grp == null)
                        grp = lsvMain.Groups.Add(date, date);

                    itm.Group = grp;
                }
            }

            if (e.Column == colGenre.Index)
            {
                lsvMain.Groups.Clear();

                foreach (ListViewItem itm in lsvMain.Items)
                {
                    string genre = itm.SubItems["colGenre"].Text;
                    ListViewGroup grp = lsvMain.Groups[genre];
                    if (grp == null)
                        grp = lsvMain.Groups.Add(genre, genre);

                    itm.Group = grp;
                }
            }
            if (e.Column == colTitle.Index)
            {
                lsvMain.Groups.Clear();

                foreach (ListViewItem itm in lsvMain.Items)
                    itm.Group = null;
            }
        }

        private void tsmiUpdate_Click(object sender, EventArgs e)
        {
            SqlLiteManagement.CloseDB();
            UpdateStatus(Properties.Resources.UpdateDatabase);
            this.Cursor = Cursors.WaitCursor;
            Application.DoEvents();
            if (FtpManager.Download("ftp://maurorogledi.myftp.org/Video/_Elenco%20Film/MyMovies.db"))
            {
                SqlLiteManagement.OpenDB("MyMovies.db");             
                TableGenre.FillGroup(lsvMain.Groups);
                TableMovies.Fill(lsvMain.Items, lsvMain.Groups);

                foreach (ColumnHeader col in lsvMain.Columns)
                    col.Width = -2;

                tsmOperation.Enabled = true;
                
            }
            this.Cursor = Cursors.Default;
            UpdateStatus(Properties.Resources.Completed);
        }

        private void tsmiUpdateOnline_Click(object sender, EventArgs e)
        {
            UpdateStatus(Properties.Resources.UpdateArchive);
            this.Cursor = Cursors.WaitCursor;
            Application.DoEvents();
            System.IO.File.Copy("MyMovies.db", @"\\SHARECNT\Video\_Elenco Film\MyMovies.db", true);
            this.Cursor = Cursors.Default;
            UpdateStatus(Properties.Resources.Completed);
        }

        private void mainForm_Resize(object sender, EventArgs e)
        {
            pictureBox1.BackgroundImage = Properties.Settings.Default.Pinned
                ? Properties.Resources.Pinned
                : Properties.Resources.Unpinned;

            if (this.WindowState != FormWindowState.Minimized)
            {
                if (Properties.Settings.Default.Pinned)
                    splitContainer1.SplitterDistance = this.Height / 2;
                else
                    splitContainer1.SplitterDistance = this.Height;
            }
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            Properties.Settings.Default.Pinned = !Properties.Settings.Default.Pinned;
            Properties.Settings.Default.Save();
            mainForm_Resize(sender, e);
        }

        private void lsvMain_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lsvMain.SelectedItems.Count > 0)
                LoadMovieInfo(lsvMain.SelectedItems[0]);
        }

        #endregion Events

        private void LoadMovieInfo(ListViewItem lvi)
        {
            lsvAudio.Items.Clear();
            lsvVideo.Items.Clear();
            if (lvi != null)
            {
                TableVideoFileInfo.Fill(lsvVideo.Items, int.Parse(lvi.Tag.ToString()));
                TableAudioFileInfo.Fill(lsvAudio.Items, int.Parse(lvi.Tag.ToString()));
            }

            foreach (ColumnHeader col in lsvAudio.Columns)
                col.Width = -2;
            foreach (ColumnHeader col in lsvVideo.Columns)
                col.Width = -2;
        }

        private void UpdateStatus(string text)
        {
            if (!statusStrip1.InvokeRequired)
                tssLabel.Text = text;
            else
                statusStrip1.BeginInvoke(new MethodInvoker(() => tssLabel.Text = text));        
        }

        private void tsmDelete_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(Properties.Resources.Delete, Properties.Resources.Warning, MessageBoxButtons.YesNo, MessageBoxIcon.Hand) == System.Windows.Forms.DialogResult.Yes)
            {
                int ID = int.Parse(lsvMain.SelectedItems[0].Tag.ToString());
                TableMovies.RemoveByID(ID);
                TableVideoFileInfo.RemoveByID(ID);
                TableAudioFileInfo.RemoveByID(ID);

                lsvMain.Items.Remove(lsvMain.SelectedItems[0]);
            }
        }

        private void tsmTouch_Click(object sender, EventArgs e)
        {
            int ID = int.Parse(lsvMain.SelectedItems[0].Tag.ToString());
            string filename = Path.Combine(myParam.ScanPath, TableMovies.FindPathByID(ID));
            if (File.Exists(filename))
            {
                File.SetCreationTime(filename, DateTime.Now);
                File.SetLastWriteTime(filename, DateTime.Now);
                TableMovies.ChangeCreationDate(ID, DateTime.Now);
                lsvMain.SelectedItems[0].SubItems["colDownload"].Text = DateTime.Now.ToString("MMMM yy");
            }
        }
    }

    public class ListViewColumnSorter : IComparer
    {
        /// <summary>
        /// Specifies the column to be sorted
        /// </summary>
        private int ColumnToSort;

        /// <summary>
        /// Specifies the order in which to sort (i.e. 'Ascending').
        /// </summary>
        private SortOrder OrderOfSort;

        /// <summary>
        /// Case insensitive comparer object
        /// </summary>
        private CaseInsensitiveComparer ObjectCompare;

        /// <summary>
        /// Class constructor.  Initializes various elements
        /// </summary>
        public ListViewColumnSorter()
        {
            // Initialize the column to '0'
            ColumnToSort = 0;

            // Initialize the sort order to 'none'
            OrderOfSort = SortOrder.None;

            // Initialize the CaseInsensitiveComparer object
            ObjectCompare = new CaseInsensitiveComparer();
        }

        /// <summary>
        /// This method is inherited from the IComparer interface.  It compares the two objects passed using a case insensitive comparison.
        /// </summary>
        /// <param name="x">First object to be compared</param>
        /// <param name="y">Second object to be compared</param>
        /// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
        public int Compare(object x, object y)
        {
            int compareResult;
            ListViewItem listviewX, listviewY;

            // Cast the objects to be compared to ListViewItem objects
            listviewX = (ListViewItem)x;
            listviewY = (ListViewItem)y;

            // Compare the two items
            if (ColumnToSort == 2)
                compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Tag, listviewY.SubItems[ColumnToSort].Tag);
            else if (ColumnToSort == 3)
                compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Tag, listviewY.SubItems[ColumnToSort].Tag);
            else
                compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text);

            // Calculate correct return value based on object comparison
            if (OrderOfSort == SortOrder.Ascending)
            {
                // Ascending sort is selected, return normal result of compare operation
                return compareResult;
            }
            else if (OrderOfSort == SortOrder.Descending)
            {
                // Descending sort is selected, return negative result of compare operation
                return (-compareResult);
            }
            else
            {
                // Return '0' to indicate they are equal
                return 0;
            }
        }

        /// <summary>
        /// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0').
        /// </summary>
        public int SortColumn
        {
            set
            {
                ColumnToSort = value;
            }
            get
            {
                return ColumnToSort;
            }
        }

        /// <summary>
        /// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending').
        /// </summary>
        public SortOrder Order
        {
            set
            {
                OrderOfSort = value;
            }
            get
            {
                return OrderOfSort;
            }
        }
    }
}